import pandas as pd
import numpy as np
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

# 显示所有列
pd.set_option('display.max_columns', None)
# 显示所有行
# pd.set_option('display.max_rows', None)
# 设置value的显示长度为100，默认为50
# pd.set_option('max_colwidth',100)

# _____读取数据_____
data = pd.read_csv('/Users/skyf/MachineLearning/sklearn/localDataSet/titanic_train.csv')

# 查看数据 处理数据：缺失值和object类型
# print(data.info())
# print(data.head())
# _____筛选特征_____
# 缺失太多的数据一般不处理 比如Cabin特征
# 删除一些列 inplace=True覆盖原data
data.drop(["Cabin", "Name", "Ticket"], inplace=True, axis=1)
# print(data.head())

# 填充缺失值为0
data["Age"] = data["Age"].fillna(data["Age"].mean())

# 删除有缺失值的行 这里指的是 Embarked中的两个缺失值
data.dropna(axis=0, inplace=True)
# print(data.info())

# 处理object类型
# 查看unique的特征类型 用list中对应的索引来替代对应的字母类型
# 一般来说特征类型无关联的情况下 就能用这种替代方式 比较方便
embarkedLabels = data["Embarked"].unique().tolist()
data["Embarked"] = data["Embarked"].apply(lambda x: embarkedLabels.index(x))
# print(data["Embarked"].unique())

# 取列多用loc和iloc
data.loc[:, "Sex"] = (data["Sex"] == "male").astype("int")
# print(data["Sex"])

# 分离X和Y（特征和结果），取出所有行，和所有列不等于Survived的数据
x = data.iloc[:, data.columns != "Survived"]
y = data.iloc[:, data.columns == "Survived"]

trainX, testX, trainY, testY = train_test_split(x, y, test_size=0.3)
# 将分割好的数据索引调整好顺序 否则数据比较容易乱
for i in [trainX, testX, trainY, testY]:
    i.index = range(i.shape[0])
print(trainX)

dtf = DecisionTreeClassifier(random_state=30)
# dtf.fit(trainX, trainY)
# score = dtf.score(testX, testY)
# print(score)

# 网格搜索
parms = {'splitter': ('best', 'random')
    , 'criterion': ('gini', 'entropy')
    , 'max_depth': [*range(1, 10)]
    , 'min_samples_leaf': [*range(1, 50, 5)]
    , 'min_impurity_decrease': [*np.linspace(0, 0.5, 20)]  # np.arange指定不长  linspace指定个数
         }
gsc = GridSearchCV(dtf, parms, cv=10)
gsc = gsc.fit(trainX, trainY)

print(gsc.best_params_)
print(gsc.best_score_)
